package com.xnyy.lottery.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyy.lottery.common.exception.CustomException;
import com.xnyy.lottery.domain.dto.DataDTO;
import com.xnyy.lottery.domain.dto.RegisterQueryDTO;
import com.xnyy.lottery.domain.entity.RegisterRecord;
import com.xnyy.lottery.domain.mapper.RegisterRecordMapper;
import com.xnyy.lottery.domain.vo.MemberRegisterParkingInfoVO;
import lombok.AllArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @auther: Administrator
 * @date: 2022/9/17 01:45
 */
@AllArgsConstructor
@Service
public class RegisterService extends ServiceImpl<RegisterRecordMapper, RegisterRecord> {
    private final TicketService ticketService;
    private final RegisterRecordMapper registerRecordMapper;

    public List<MemberRegisterParkingInfoVO> selectList(RegisterQueryDTO dto) {
        return registerRecordMapper.selectObjectList(dto);
    }

    private void check(RegisterRecord registerRecord) {

        if (registerRecord.getSelectType() == null) {
            throw new CustomException("登记类型不能为空");
        }
        if (registerRecord.getSelectType() < 1 || registerRecord.getSelectType() > 2) {
            throw new CustomException("登记类型范围：1、2");
        }
        if (StrUtil.isBlank(registerRecord.getWorkNo())) {
            throw new CustomException("登记号不能为空");
        }
        if (StrUtil.isBlank(registerRecord.getSerialNumber())) {
            throw new CustomException("系统生成序号不能为空");
        }
        //签到登记
        if (registerRecord.getSelectType() == 1) {
            if (StrUtil.isBlank(registerRecord.getRegion())) {
                throw new CustomException("请选择区域");
            }
        } else if (registerRecord.getSelectType() == 2) {//流选登记
            if (registerRecordMapper.existsByResult(registerRecord.getWorkNo(), 2) < 1) {
                throw new CustomException("还未摇号");
            }
        }
        //已经在该区域登记过
        if (this.lambdaQuery()
                .eq(RegisterRecord::getWorkNo, registerRecord.getWorkNo())
                .eq(registerRecord.getRegion() != null, RegisterRecord::getRegion, registerRecord.getRegion())
                .exists()) {
            throw new CustomException("重复登记");
        }
        //重复登记 
        if (this.lambdaQuery().eq(RegisterRecord::getBarCode, registerRecord.getBarCode()).exists()) {
            throw new CustomException("重复登记");
        }

        //已经选位不能再登记
        if (registerRecordMapper.existsByResult(registerRecord.getWorkNo(), 1) > 0) {
            throw new CustomException("登记人员已选位，不能再登记");
        }
    }

    /**
     * 注册并生成号码
     */
    @Transactional(rollbackFor = Exception.class)
    public RegisterRecord register(RegisterRecord registerRecord) {
        if (registerRecord.getSelectType() == 1) {
            DataDTO data = ticketService.getData();
            registerRecord.setRegion(data.getRegion());
            registerRecord.setWorkNo(data.getWorkNo());
        } else {
            MemberRegisterParkingInfoVO parkingInfoVO = this.getByBarCode(registerRecord.getBarCode());
            registerRecord.setRegion("");
            registerRecord.setWorkNo(parkingInfoVO.getWorkNo());
        }
        ticketService.generate(registerRecord);
        registerRecord.setId(null);
        registerRecord.setResult(0);
        registerRecord.setRegion(StrUtil.trimToEmpty(registerRecord.getRegion()));
        registerRecord.setCurrentTimes(0);
        registerRecord.setCreateTime(new Date());
        this.check(registerRecord);
        registerRecordMapper.insert(registerRecord);
        return registerRecord;
    }

    @Transactional(rollbackFor = Exception.class)
    public void lose(String barCode) {
        RegisterRecord registerRecord = registerRecordMapper.selectByBarCode(barCode);
        if (registerRecord == null) {
            throw new CustomException("登记号错误！");
        }
        if (registerRecordMapper.existsByResult(registerRecord.getWorkNo(), 1) > 0) {
            throw new CustomException("该登记号已选车位，无需执行流选操作！");
        }
        int currentTimes = registerRecord.getCurrentTimes() == null ? 0 : registerRecord.getCurrentTimes();
        if (currentTimes < RegisterRecord.MAX_TIMES) {
            throw new CustomException("当前区域选位次数还剩:" + (RegisterRecord.MAX_TIMES - currentTimes));
        }
        registerRecord.setResult(2);
        if (registerRecordMapper.updateById(registerRecord) <= 0) {
            throw new CustomException("流选操作更新失败");
        }
    }

    public List<String> getRegionByworkNo(String workNo) {

        return this.lambdaQuery().select(RegisterRecord::getRegion)
                .eq(RegisterRecord::getWorkNo, workNo)
                .list()
                .stream()
                .map(RegisterRecord::getRegion)
                .collect(Collectors.toList());
    }

    public MemberRegisterParkingInfoVO getRegisterParkingInfo(Long id) {
        return registerRecordMapper.selectRegisterParkingInfo(id);
    }

    public MemberRegisterParkingInfoVO getByBarCode(String barCode) {
        return registerRecordMapper.getByBarCode(barCode);
    }

    /**
     * 主动放弃放弃
     *
     * @param barCode
     */
    @Transactional(rollbackFor = Exception.class)
    public void givup(String barCode) {
        RegisterRecord registerRecord = this.givupRegisterRecord(barCode);
        if (registerRecord.getSelectType() == 1) {
            final RegisterRecord newRecord = new RegisterRecord();
            newRecord.setWorkNo(registerRecord.getWorkNo());
            newRecord.setSelectType(2);
            //重新注册并放弃
            final RegisterRecord register = this.register(newRecord);
            this.givupRegisterRecord(register.getBarCode());
        }
    }

    @NotNull
    private RegisterRecord givupRegisterRecord(String barCode) {
        RegisterRecord registerRecord = registerRecordMapper.selectByBarCode(barCode);
        if (registerRecord == null) {
            throw new CustomException("操作失败！");
        }
        if (registerRecordMapper.existsByResult(registerRecord.getWorkNo(), 1) > 0) {
            throw new CustomException("该登记号已选车位，无需执行该操作！");
        }
        registerRecord.setCurrentTimes(2);
        registerRecord.setResult(2);
        if (registerRecordMapper.updateById(registerRecord) <= 0) {
            throw new CustomException("操作更新失败");
        }
        return registerRecord;
    }
}
